package assist.domain.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;




public class StatsQuery implements Serializable
{
    private static final long serialVersionUID = 1L;  
    
    public enum StatType {FOR, AGAINST, RATIO}
    public enum Strength {ALL, EV, PP, SH}    
    public enum ShotType {SOG, MISS, BLOCK, CORSI, FENWICK}  
    private Set<Column> columns = new TreeSet<Column>();
    private Team team;
    private Set<String> gameIds;      
    private List<RowQuery> rowQueries = new ArrayList<RowQuery>();
    private Set<Long> playerIds = new TreeSet<Long>();
    private Map<Long, Set<Long>> playerWowys = new TreeMap<Long, Set<Long>>();
    
    public StatsQuery(final Team team)
    {       
        this.team = team;
    }

    
    /**
     * @return the strength
     */
    public Set<Column> getColumns()
    {
        return this.columns;
    }
    /**
     * @param events the events to set
     */
    public void addColumn(Column column)
    {
        this.columns.add(column);
    }

    public Team getTeam()
    {        
        return this.team;
    }

 
        
    public void setPlayers(Set<Player> players)
    {
        playerIds.clear();
        for (Player player: players)
        {
            playerIds.add(player.getPlayerId());
        }

    }
    
    public void addPlayerId(Long playerId)
    {        
        playerIds.add(playerId);
    }     
   


    public Set<Long> getPlayerIds()
    {
        return this.playerIds;
    }    
    

    public void setPlayerWowy(Player player, Set<Player> wowyPlayers)
    {
       Set<Long> wowyPlayerIds = new TreeSet<Long>();
       for(Player wowyPlayer: wowyPlayers)
       {
           wowyPlayerIds.add(wowyPlayer.getPlayerId());
       }
       this.setPlayerWowyIds(player.getPlayerId(), wowyPlayerIds);       
    }
    
    public void setPlayerWowyIds(Long playerId, Set<Long> wowyPlayerIds)
    {
        playerWowys.put(playerId, wowyPlayerIds);
    }
    public Set<Long> getPlayerWowyIds(Player player)
    {
        return this.getPlayerWowyIds(player.getPlayerId());
    }
    
    public Set<Long> getPlayerWowyIds(Long playerId)
    {
        return playerWowys.get(playerId);
    }
    
    public Map<Long, Set<Long>> getPlayerWowyIdsMap()
    {
        return this.playerWowys;
    }
    
    public void addPlayerWowyId(Long playerId, Long wowyPlayerId)
    {
        Set<Long> wowyPlayerIds = this.playerWowys.get(playerId);
        if (wowyPlayerIds == null)
        {
            wowyPlayerIds = new TreeSet<Long>();
            this.playerWowys.put(playerId, wowyPlayerIds);
        }
        wowyPlayerIds.add(wowyPlayerId);
    }
    
    
    
    /**
     * Updates all row Queries to use the current team, columns, games.
     * @return
     */
    public List<RowQuery> getRowQueries()
    {
        rowQueries.clear();
        rowQueries.add(new RowQuery(this.team, this.gameIds, this.columns));            
        for (Long playerId : playerIds)
        {
            rowQueries.add(new RowQuery(this.team, this.gameIds, this.columns, playerId));
        }        
        for (Long playerId : this.playerWowys.keySet())
        {
            Set<Long> playerWowy = this.playerWowys.get(playerId);
            
            for (Long wowyPlayer : playerWowy)
            {
                rowQueries.add(new RowQuery(this.team, this.gameIds, this.columns, playerId, wowyPlayer));
            }
        } 
        return rowQueries;
    }    
    
    
    public static class RowQuery implements Serializable
    {
        private static final long serialVersionUID = 1L;
        private Set<Long> playerIds = new TreeSet<Long>();
        private Set<String> gameIds;
        private Set<Column> columns;
        private Team team;
        private String title;
        RowQuery(){}


        public RowQuery(Team team, Set<String> gameIds,
                Set<Column> columns, Long... playerIds)
        {
            this(team, gameIds, columns);
            for (Long playerId : playerIds)
            {
                this.playerIds.add(playerId);
            }
        }
        
        public RowQuery(Team team, Set<String> gameIds,
                Set<Column> columns)
        {
            this.config(gameIds, columns);
            this.team = team;
        }        
        
        
        public void config(Set<String> gameIds, Set<Column> columns)
        {
            this.gameIds = gameIds;
            this.columns = columns;
        }        

        public Set<String> getGameIds()
        {
            return this.gameIds;
        }

        public Set<Column> getColumns()
        {            
            return this.columns;
        }

        public Team getTeam()
        {           
            return this.team;
        }

        public Set<Long> getPlayerIds()
        {
            // TODO Auto-generated method stub
            return this.playerIds;
        }
        


        public void setTitle(String title)
        {
System.err.println("Setting title for:" + this.playerIds);
System.err.println("title:" + title);
            this.title = title;      
        }
        public String getTitle()
        {
            return this.title;     
        }
    }
    
    
    public static class Column implements Serializable, Comparable<Column>
    {        
        private static final long serialVersionUID = 1L;
        private ShotType shotType;
        private Strength strength;              
        private StatType statType;
        
        Column(){}

        public Column(ShotType shotType, Strength strength, StatType statType)
        {
            this.shotType = shotType;
            this.strength = strength;
            this.statType = statType;                
        }
        @Override
        public String toString()
        {
            return this.shotType + "," + this.strength + "," + this.statType;
        }
        
        public Strength getStrength()
        {
            return this.strength;
        }
        
        public ShotType getShotType()
        {
            return this.shotType;
        }
        
        public StatType getStatType()
        { 
            return this.statType;            
        }        
        
        @Override
        public int compareTo(Column col)
        {
            if ( this == col )
            {
                return 0;
            }
            int comparison = 0;
            comparison = this.shotType.compareTo(col.shotType);
            if ( comparison != 0 )
            {
                return comparison;
            }
            comparison = this.strength.compareTo(col.strength);
            if ( comparison != 0 )
            {
                return comparison;
            }
            comparison = this.statType.compareTo(col.statType);
            if ( comparison != 0 )
            {
                return comparison;
            }
            return 0;
        }

    }


    public void setGameIds(Set<String> gameIds)
    {
        this.gameIds = gameIds;
    }


    public int getNumRowQueries()
    {
        // TODO Auto-generated method stub
        return this.rowQueries.size();
    }



}
